/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package acousticfield3d.gui.misc;

import acousticfield3d.algorithms.SimplePhaseAlgorithms;
import acousticfield3d.gui.MainForm;
import acousticfield3d.math.M;
import acousticfield3d.math.Vector2f;
import acousticfield3d.math.Vector3f;
import acousticfield3d.scene.Entity;
import acousticfield3d.scene.Scene;
import acousticfield3d.simulation.Transducer;
import acousticfield3d.utils.Parse;
import java.util.ArrayList;

/**
 *
 * @author am14010
 */
public class HybridSingleBeamForm extends javax.swing.JFrame {
    final MainForm mf;
    
    public HybridSingleBeamForm(MainForm mf) {
        this.mf = mf;
        initComponents();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        dividerGroup = new javax.swing.ButtonGroup();
        aGroup = new javax.swing.ButtonGroup();
        bGroup = new javax.swing.ButtonGroup();
        circleCheck = new javax.swing.JRadioButton();
        circleText = new javax.swing.JTextField();
        halfCheck = new javax.swing.JRadioButton();
        checkerCheck = new javax.swing.JRadioButton();
        jLabel1 = new javax.swing.JLabel();
        aFocusCheck = new javax.swing.JRadioButton();
        aVortexCheck = new javax.swing.JRadioButton();
        aVortexText = new javax.swing.JTextField();
        bVortexText = new javax.swing.JTextField();
        bVortexCheck = new javax.swing.JRadioButton();
        bFocusCheck = new javax.swing.JRadioButton();
        jLabel2 = new javax.swing.JLabel();
        setButton = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

        dividerGroup.add(circleCheck);
        circleCheck.setSelected(true);
        circleCheck.setText("circle");

        circleText.setText("0.7");

        dividerGroup.add(halfCheck);
        halfCheck.setText("half");

        dividerGroup.add(checkerCheck);
        checkerCheck.setText("checker");

        jLabel1.setText("A)");

        aGroup.add(aFocusCheck);
        aFocusCheck.setSelected(true);
        aFocusCheck.setText("focus");

        aGroup.add(aVortexCheck);
        aVortexCheck.setText("vortex");

        aVortexText.setText("1");

        bVortexText.setText("1");

        bGroup.add(bVortexCheck);
        bVortexCheck.setText("vortex");

        bGroup.add(bFocusCheck);
        bFocusCheck.setSelected(true);
        bFocusCheck.setText("focus");

        jLabel2.setText("B)");

        setButton.setText("Set");
        setButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                setButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(circleCheck)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(circleText, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(halfCheck)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(checkerCheck))
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                        .addGroup(layout.createSequentialGroup()
                            .addComponent(jLabel2)
                            .addGap(18, 18, 18)
                            .addComponent(bFocusCheck)
                            .addGap(18, 18, 18)
                            .addComponent(bVortexCheck)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                            .addComponent(bVortexText, javax.swing.GroupLayout.PREFERRED_SIZE, 54, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGroup(layout.createSequentialGroup()
                            .addComponent(jLabel1)
                            .addGap(18, 18, 18)
                            .addComponent(aFocusCheck)
                            .addGap(18, 18, 18)
                            .addComponent(aVortexCheck)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                            .addComponent(aVortexText, javax.swing.GroupLayout.PREFERRED_SIZE, 54, javax.swing.GroupLayout.PREFERRED_SIZE)))
                    .addComponent(setButton))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(circleCheck)
                    .addComponent(circleText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(halfCheck)
                    .addComponent(checkerCheck))
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(aFocusCheck)
                    .addComponent(aVortexCheck)
                    .addComponent(aVortexText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(bFocusCheck)
                    .addComponent(bVortexCheck)
                    .addComponent(bVortexText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(setButton)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void setButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_setButtonActionPerformed
        final ArrayList<Transducer> trans = mf.simulation.transducers;
        
        //calc array center
        final Vector3f center = new Vector3f();
        for(Transducer t : trans){
            center.addLocal( t.getTransform().getTranslation() );
        }
        center.divideLocal( trans.size() );
        float maxDistance = 0;
        float minDistance = Float.MAX_VALUE;
        for(Transducer t : trans){
            final Vector3f tPos = t.getTransform().getTranslation();
            final float distance = tPos.distance(center);
            maxDistance = M.max(maxDistance, distance );
            minDistance = M.min(minDistance, distance );
        }
        
        //get selected point
        Entity cp = Scene.getFirstWithTag( mf.getSelection(), Entity.TAG_CONTROL_POINT );
        if (cp == null){
            return;
        }
        final Vector3f focusPoint = cp.getTransform().getTranslation();
        final float mSpeed = mf.simulation.getMediumSpeed();
        
        final boolean circle = circleCheck.isSelected();
        final boolean half = halfCheck.isSelected();
        final boolean checker = checkerCheck.isSelected();
        final float circleA = Parse.toFloat( circleText.getText() );
        
        final boolean aFocus = aFocusCheck.isSelected();
        final boolean bFocus = bFocusCheck.isSelected();
        final float vortexA = Parse.toFloat( aVortexText.getText() );
        final float vortexB = Parse.toFloat( bVortexText.getText() );
        
        
        //iterate through transducers
        for(Transducer t : trans){
            final Vector3f tPos = t.getTransform().getTranslation();
            final float distanceToFocus = tPos.distance(focusPoint);
            final float nDistanceToCenter = (tPos.distance(center) - minDistance) / (maxDistance - minDistance);
            final float angleToCenter = new Vector2f(tPos.x - center.x, tPos.z - center.z).getAngle();
            
            //add focus
            SimplePhaseAlgorithms.focus(t, focusPoint, mSpeed);
                    
            //is in A or B
            boolean isA = true;
            if (circle){
                isA = nDistanceToCenter < circleA;
            }else if(half){
                isA = logicalXOR(angleToCenter > 0, nDistanceToCenter < circleA);
            }else if (checker){
                boolean isQuadrandOdd = ( M.floor( (angleToCenter + M.PI) / M.TWO_PI * 4 )  % 2) == 0;
                
                isA = logicalXOR( isQuadrandOdd, nDistanceToCenter < circleA);
            }
       
            
            if (isA){
                if (aFocus){
                    
                }else{
                    t.phase += angleToCenter * vortexA / M.PI;
                }
            }else{
                t.phase += 1;
                if (bFocus){
                    
                }else{
                    t.phase += angleToCenter * vortexB / M.PI;
                }
            }
        }
        
        mf.needUpdate();
    }//GEN-LAST:event_setButtonActionPerformed

    public static boolean logicalXOR(boolean x, boolean y) {
        return ( ( x || y ) && ! ( x && y ) );
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JRadioButton aFocusCheck;
    private javax.swing.ButtonGroup aGroup;
    private javax.swing.JRadioButton aVortexCheck;
    private javax.swing.JTextField aVortexText;
    private javax.swing.JRadioButton bFocusCheck;
    private javax.swing.ButtonGroup bGroup;
    private javax.swing.JRadioButton bVortexCheck;
    private javax.swing.JTextField bVortexText;
    private javax.swing.JRadioButton checkerCheck;
    private javax.swing.JRadioButton circleCheck;
    private javax.swing.JTextField circleText;
    private javax.swing.ButtonGroup dividerGroup;
    private javax.swing.JRadioButton halfCheck;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JButton setButton;
    // End of variables declaration//GEN-END:variables
}
